package myJs.cps

import myJs.cps.Style
import myJs.myPkg.reactHookForm._
import org.scalajs.dom.html.Input
import org.scalajs.dom.{Event, html}
import slinky.core.annotations.react
import slinky.core.facade.Fragment
import slinky.core.facade.Hooks.{useEffect, useLayoutEffect, useRef}
import slinky.core.{FunctionalComponent, SyntheticEvent, TagElement}
import slinky.web.html._

import scala.scalajs.js
import myJs.Implicits._
import slinky.web.SyntheticFocusEvent

/** Created by yz on 3/11/2020
  */
@react object PureInputCp {

  case class Props(
      useForm: UseFormRT,
      name: String = "",
      readOnly: Boolean = false,
      required: Boolean = true,
      registerOptions: RegisterOptions = RegisterOptions(),
      onChange: js.UndefOr[String => Unit] = js.undefined,
      showValidate: Boolean = true,
      value: String = "",
      width: String = "",
      placeHolder: String = "",
      `type`: String = "",
      maxLength: js.UndefOr[Int] = js.undefined,
      onFocus: js.UndefOr[html.Input => Unit] = js.undefined,
      onBlur: js.UndefOr[() => Unit] = js.undefined,
      selfClassName: String = "",
      autoComplete: String = "on"
  )

  val component = FunctionalComponent[Props] { props =>
    val firstUpdate = useRef(true)

    object FTool {

      def focusF = (e: SyntheticFocusEvent[TagElement#RefType]) => {
        val inputE = e.target.asInstanceOf[html.Input]
        props.onFocus.foreach(_(inputE))
      }

    }

    val valueOp = props.useForm.watch(props.name)

    useEffect(
      () => {
        if (!props.readOnly && !firstUpdate.current) {
          val v = valueOp.asInstanceOf[js.UndefOr[String]].getOrElse("")
          if (v != props.value) {
            props.onChange.foreach(_(v))
          }

        }
      },
      List(valueOp)
    )

    useEffect(
      () => {
        val v = valueOp.asInstanceOf[js.UndefOr[String]].getOrElse("")
        if (v != props.value) {
          props.useForm.setValue(props.name, props.value)
          props.useForm.trigger(props.name)
        }
      },
      List(props.value)
    )

    useEffect(
      () => {
        if (firstUpdate.current) {
          firstUpdate.current = false
        }
      },
      List()
    )

    Fragment(
      Controller(
        name = props.name,
        control = props.useForm.control,
        rules = props.registerOptions,
        defaultValue = props.value,
        render = (fieldR: FieldR) => {
          val field = fieldR.field
          val fieldV = field.value.asInstanceOf[String]
          input(
            style := Style(width = props.width),
            className := s"form-control ${props.selfClassName}",
            name := field.name,
            value := fieldV,
            onChange := field.onChange,
            ref := field.ref,
            readOnly := props.readOnly,
            placeholder := props.placeHolder,
            `type` := props.`type`,
            onFocus := FTool.focusF,
            autoComplete := props.autoComplete,
            onBlur := props.onBlur.toOption
          )()
        }
      ),
      if (
        props.showValidate && props.useForm.formState.errors
          .deepDefinedAt(props.name)
      ) {
        small(
          className := "help-block",
          props.useForm.formState.errors.deepGet(props.name).message
        )
      } else null
    )

  }

}
